package com.gitee.wsl.serialization.param

import kotlinx.serialization.KSerializer
import kotlin.reflect.KClass


interface ValueWithSerializer<T : Any> {
    val value: T
    val serializer: KSerializer<T>
    val cls: KClass<T>

    fun asParam(): ParamSerializer<T> = ParamSerializer.Custom(serializer, cls)

    companion object {
        inline operator fun <reified T : Any> invoke(
            value: T,
            serializer: KSerializer<T>
        ): ValueWithSerializer<T> =
            ConcreteValueWithSerializer<T>(value, serializer, T::class)
    }
}

@PublishedApi
internal data class ConcreteValueWithSerializer<T : Any>(
    override val value: T,
    override val serializer: KSerializer<T>,
    override val cls: KClass<T>
) : ValueWithSerializer<T>

interface ValuesWithSerializer<T : Any> {
    val values: List<T>
    val serializer: KSerializer<T>
    val cls: KClass<T>

    fun asParam(): ParamSerializer<T> = ParamSerializer.Custom(serializer, cls)

    companion object {
        operator inline fun <reified T : Any> invoke(
            values: List<T>,
            serializer: KSerializer<T>
        ): ValuesWithSerializer<T> =
            ConcreteValuesWithSerializer<T>(values, serializer, T::class)
    }
}

@PublishedApi
internal data class ConcreteValuesWithSerializer<T : Any>(
    override val values: List<T>,
    override val serializer: KSerializer<T>,
    override val cls: KClass<T>
) : ValuesWithSerializer<T>
